home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libcan / canmisc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  5.5 KB  |  219 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *     canmisc -
  19.  *        Miscellaneous operations.
  20.  *
  21.  *                Paul Haeberli - 1991
  22.  *
  23.  *    exports
  24.  *
  25.     void onefield(c,fieldno);
  26.     void fieldfilter(c,thresh);
  27.     void blendcanvas(a,b,c,f);
  28.     void diffcanvas(a,b,c);
  29.  *
  30.  */
  31. #include "stdio.h"
  32. #include "canvas.h"
  33. #include "math.h"
  34. #include "lum.h"
  35.  
  36. void onefield(c,fieldno)
  37. canvas *c;
  38. int fieldno;
  39. {
  40.     int y ,sy1, sy2, n;
  41.     unsigned char *sptr1, *sptr2, *dptr;
  42.  
  43.     fieldno &= 1;
  44.     fieldno ^= 1;
  45.     for(y=fieldno; y<c->ysize; y+=2) {
  46.     sy1 = y-1;
  47.     sy2 = y+1;
  48.     if(sy1<0) sy1 = 0;
  49.     if(sy1>=c->ysize) sy1 = c->ysize-1;
  50.     if(sy2<0) sy2 = 0;
  51.     if(sy2>=c->ysize) sy2 = c->ysize-1;
  52.     sptr1 = (unsigned char *)(c->data+sy1*c->xsize);
  53.     sptr2 = (unsigned char *)(c->data+sy2*c->xsize);
  54.     dptr = (unsigned char *)(c->data+y*c->xsize);
  55.     n = c->xsize;
  56.     while(n--) {
  57.         dptr[OFFSET_R] = (sptr1[OFFSET_R]+sptr2[OFFSET_R])/2;
  58.         dptr[OFFSET_G] = (sptr1[OFFSET_G]+sptr2[OFFSET_G])/2;
  59.         dptr[OFFSET_B] = (sptr1[OFFSET_B]+sptr2[OFFSET_B])/2;
  60.         dptr += 4;
  61.         sptr1 += 4;
  62.         sptr2 += 4;
  63.     }
  64.     }
  65. }
  66.  
  67. void fieldfilter(c,thresh)
  68. canvas *c;
  69. int thresh;
  70. {
  71.     int y ,sy1, sy2, n, lum, lum1, lum2, dl, lumlow, lumhi;
  72.     unsigned char *sptr1, *sptr2, *dptr;
  73.  
  74.     for(y=0; y<c->ysize; y+=2) {
  75.         sy1 = y-1;
  76.         sy2 = y+1;
  77.         if(sy1<0) sy1 = 0;
  78.         if(sy1>=c->ysize) sy1 = c->ysize-1;
  79.         if(sy2<0) sy2 = 0;
  80.         if(sy2>=c->ysize) sy2 = c->ysize-1;
  81.         sptr1 = (unsigned char *)(c->data+sy1*c->xsize);
  82.         sptr2 = (unsigned char *)(c->data+sy2*c->xsize);
  83.         dptr = (unsigned char *)(c->data+y*c->xsize);
  84.         n = c->xsize;
  85.         while(n--) {
  86.             lum1 = ILUM(sptr1[OFFSET_R],sptr1[OFFSET_G],sptr1[OFFSET_B]);
  87.             lum2 = ILUM(sptr2[OFFSET_R],sptr2[OFFSET_G],sptr2[OFFSET_B]);
  88.             lum = ILUM(dptr[OFFSET_R],dptr[OFFSET_G],dptr[OFFSET_B]);
  89.         if(lum2>lum1) {
  90.         lumlow = lum1-thresh;
  91.         lumhi = lum2+thresh;
  92.         } else {
  93.         lumlow = lum2-thresh;
  94.         lumhi = lum1+thresh;
  95.         }
  96.         if(lum<lumlow || lum>lumhi) {
  97.         dptr[OFFSET_R] = (sptr1[OFFSET_R]+sptr2[OFFSET_R])/2;
  98.         dptr[OFFSET_G] = (sptr1[OFFSET_G]+sptr2[OFFSET_G])/2;
  99.         dptr[OFFSET_B] = (sptr1[OFFSET_B]+sptr2[OFFSET_B])/2;
  100.          }
  101.             dptr += 4;
  102.             sptr1 += 4;
  103.             sptr2 += 4;
  104.         }
  105.     }
  106. }
  107.  
  108. #define BLERP(v1,v2,a)    ( (v1)+ (((((v2)-(v1))*(a))+127)>>8) )
  109.  
  110. void blendcanvas(a,b,c,f)
  111. canvas *a, *b, *c;
  112. float f;
  113. {
  114.     unsigned char *aptr, *bptr, *cptr;
  115.     unsigned long *laptr, *lbptr, *lcptr;
  116.     short aa, v;
  117.     int n;
  118.      
  119.     saverect(c,&c->area);
  120.     if((a->xsize != b->xsize) || (a->ysize != b->ysize) || 
  121.        (a->xsize != c->xsize) || (a->ysize != c->ysize) ) {
  122.     fprintf(stderr,"blendcanvas: all canvases must be the same size\n");
  123.     return;
  124.     }
  125.     aa = 256*f;
  126.     laptr = a->data;
  127.     lbptr = b->data;
  128.     lcptr = c->data;
  129.     n = a->xsize*a->ysize;
  130.     if(f>=0.0 && f<= 1.0) {
  131.     while(n--) {
  132.         if(*laptr == *lbptr) {
  133.         *lcptr = *laptr;
  134.         } else {
  135.         aptr = (unsigned char *)laptr;
  136.         bptr = (unsigned char *)lbptr;
  137.         cptr = (unsigned char *)lcptr;
  138.         cptr[OFFSET_R] = BLERP(aptr[OFFSET_R],bptr[OFFSET_R],aa);
  139.         cptr[OFFSET_G] = BLERP(aptr[OFFSET_G],bptr[OFFSET_G],aa);
  140.         cptr[OFFSET_B] = BLERP(aptr[OFFSET_B],bptr[OFFSET_B],aa);
  141.         }
  142.         laptr++;
  143.         lbptr++;
  144.         lcptr++;
  145.     }
  146.     } else {
  147.     while(n--) {
  148.         if(*laptr == *lbptr) {
  149.         *lcptr = *laptr;
  150.         } else {
  151.         aptr = (unsigned char *)laptr;
  152.         bptr = (unsigned char *)lbptr;
  153.         cptr = (unsigned char *)lcptr;
  154.         v = BLERP(aptr[OFFSET_R],bptr[OFFSET_R],aa);
  155.         if(v&0xff00) {
  156.             if(v<0) v = 0; else v = 255;
  157.         }
  158.         cptr[OFFSET_R] = v;
  159.         v = BLERP(aptr[OFFSET_G],bptr[OFFSET_G],aa);
  160.         if(v&0xff00) {
  161.             if(v<0) v = 0; else v = 255;
  162.         }
  163.         cptr[OFFSET_G] = v;
  164.         v = BLERP(aptr[OFFSET_B],bptr[OFFSET_B],aa);
  165.         if(v&0xff00) {
  166.             if(v<0) v = 0; else v = 255;
  167.         }
  168.         cptr[OFFSET_B] = v;
  169.         }
  170.         laptr++;
  171.         lbptr++;
  172.         lcptr++;
  173.     }
  174.     }
  175.     touchcanvas(c);
  176.     flushcanvas(c);
  177. }
  178.  
  179. void diffcanvas(a,b,c)
  180. canvas *a, *b, *c;
  181. {
  182.     unsigned char *aptr, *bptr, *cptr;
  183.     short aa, v;
  184.     int n;
  185.      
  186.     saverect(c,&c->area);
  187.     if((a->xsize != b->xsize) || (a->ysize != b->ysize) || 
  188.        (a->xsize != c->xsize) || (a->ysize != c->ysize) ) {
  189.     fprintf(stderr,"diffcanvas: all canvases must be the same size\n");
  190.     return;
  191.     }
  192.     aptr = (unsigned char *)a->data;
  193.     bptr = (unsigned char *)b->data;
  194.     cptr = (unsigned char *)c->data;
  195.     n = a->xsize*a->ysize;
  196.     while(n--) {
  197.     v = 128+aptr[OFFSET_R]-bptr[OFFSET_R];
  198.     if(v&0xff00) {
  199.         if(v<0) v = 0; else v = 255;
  200.     }
  201.     cptr[OFFSET_R] = v;
  202.     v = 128+aptr[OFFSET_G]-bptr[OFFSET_G];
  203.     if(v&0xff00) {
  204.         if(v<0) v = 0; else v = 255;
  205.     }
  206.     cptr[OFFSET_G] = v;
  207.     v = 128+aptr[OFFSET_B]-bptr[OFFSET_B];
  208.     if(v&0xff00) {
  209.         if(v<0) v = 0; else v = 255;
  210.     }
  211.     cptr[OFFSET_B] = v;
  212.     aptr += 4;
  213.     bptr += 4;
  214.     cptr += 4;
  215.     }
  216.     touchcanvas(c);
  217.     flushcanvas(c);
  218. }
  219.